package threadLock.LongAdder;

import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import java.util.concurrent.*;
import java.util.concurrent.atomic.LongAdder;

/**
 * LongAdder 为了解决AtomicLong在高并发下的性能问题诞生的
 * 内部维护了一个cell动态数组 多个线程争抢多个资源 如果cell元素争抢失败 会再去尝试争抢别的cell元素
 * 当前代码也可能出现命令重排序
 */
public class LongAdderTest {
    private static LongAdder longAdder = new LongAdder();

    public static void main(String[] args) {
//        for (int i = 0; i < 20; i++) {
//            increment();
//        }
//        System.out.println("mainThread: "+longAdder.sumThenReset());
        new LongAdderThreadPoll().longAdderTest();
    }

    private static void increment(){
        Thread sonThread = new Thread(()->{
            longAdder.increment();
            System.out.println(longAdder.longValue());
        }, "sonThread");
        sonThread.start();
    }
}

/**
 * 线程池测试
 * 线程池在后续补充
 */
class LongAdderThreadPoll{
    public void longAdderTest(){
        int core = Runtime.getRuntime().availableProcessors();
        int maxCore = core * 2;
        //线程回收时间 线程个数大于核心个数 回收空闲线程
        Long keepAliveTime = 0L;
        // 阻塞队列  每个线程的命名 拒绝策略
        LinkedBlockingQueue objects = new LinkedBlockingQueue();
        CustomizableThreadFactory customizableThreadFactory = new CustomizableThreadFactory("ThreadName=");
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

        ThreadPoolExecutor threadPoolExecutor
                = new ThreadPoolExecutor(core, maxCore, keepAliveTime, TimeUnit.SECONDS, objects, customizableThreadFactory, handler);
        Semaphore semaphore = new Semaphore(maxCore);
        CountDownLatch countDownLatch = new CountDownLatch(maxCore);
        LongAdder longAdder = new LongAdder();
        try {
            for (int i = 0; i < maxCore; i++) {
                threadPoolExecutor.submit(()->{
                    try {
                        semaphore.acquire();
                        longAdder.increment();
                        System.out.println(Thread.currentThread().getName()+"值: "+longAdder);
                        semaphore.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPoolExecutor.shutdown();
        }
    }
}